package teemo

import (
	"fmt"
	"reflect"
	"strconv"
	"strings"

	"github.com/bytedance/sonic"
)

func StructJsonTagToStrMap(obj interface{}) (map[string]string, error) {
	if obj == nil {
		return nil, nil
	}

	// 使用反射获取结构体字段值
	v := reflect.ValueOf(obj)
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	// 根据字段类型进行转换
	switch v.Kind() {
	case reflect.String:
		return handleJSONString(v.String())
	case reflect.Map:
		return handleMapValue(v)
	case reflect.Struct:
		return handleStructValue(v)
	default:
		return nil, fmt.Errorf("unsupported type: %v", v.Kind())
	}

}

// convertValue 将反射值转换为字符串
func convertValue(value reflect.Value) string {
	if !value.IsValid() || value.Kind() == reflect.Ptr && value.IsNil() {
		return ""
	}
	if value.Kind() == reflect.Ptr {
		value = value.Elem()
	}
	//判空
	switch value.Kind() {
	case reflect.String:
		return value.String()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return strconv.FormatInt(value.Int(), 10)
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return strconv.FormatUint(value.Uint(), 10)
	case reflect.Float32:
		return strconv.FormatFloat(value.Float(), 'f', 5, 32)
	case reflect.Float64:
		return strconv.FormatFloat(value.Float(), 'f', -1, 64)
	case reflect.Bool:
		return strconv.FormatBool(value.Bool())
	case reflect.Complex64, reflect.Complex128:
		return fmt.Sprintf("%v", value.Complex())
	case reflect.Array, reflect.Slice, reflect.Map, reflect.Struct:
		result, err := sonic.Marshal(value.Interface())
		if err != nil {
			return fmt.Sprintf("%v", value.Interface())
		}
		return string(result)
	default:
		return fmt.Sprintf("%v", value.Interface())
	}
}

// handleMapValue 处理map类型的值
func handleMapValue(value reflect.Value) (map[string]string, error) {
	if value.Len() == 0 {
		return make(map[string]string), nil
	}

	mapStr := make(map[string]string, value.Len())
	keys := value.MapKeys()
	for _, key := range keys {
		mapValue := value.MapIndex(key)
		if mapValue.Kind() == reflect.Ptr && !mapValue.IsNil() {
			mapValue = mapValue.Elem()
		}
		mapStr[convertValue(key)] = convertValue(mapValue)
	}

	return mapStr, nil
}

// handleStructValue 处理结构体类型的值
func handleStructValue(value reflect.Value) (map[string]string, error) {
	if value.Kind() == reflect.Ptr {
		value = value.Elem()
	}
	// 遍历结构体，解析json tag
	numFields := value.NumField()
	result := make(map[string]string, numFields)
	for i := 0; i < numFields; i++ {
		field := value.Type().Field(i)
		fieldValue := value.Field(i)
		if fieldValue.Kind() == reflect.Ptr && !fieldValue.IsNil() {
			fieldValue = fieldValue.Elem()
		}
		jsonTag := field.Tag.Get("json")
		if jsonTag != "" {
			jsonTag = strings.Split(jsonTag, ",")[0]
			if jsonTag == "-" || jsonTag == "" {
				result[field.Name] = convertValue(fieldValue)
				continue
			}
			result[jsonTag] = convertValue(fieldValue)
		} else {
			result[field.Name] = convertValue(fieldValue)
		}
	}

	return result, nil
}

// handleJSONString 处理JSON字符串
func handleJSONString(str string) (map[string]string, error) {
	if !strings.HasPrefix(str, "{") || !strings.HasSuffix(str, "}") {
		return nil, fmt.Errorf("invalid JSON string")
	}

	var jsonMap map[string]interface{}
	if err := sonic.Unmarshal([]byte(str), &jsonMap); err != nil {
		return nil, err
	}

	result := make(map[string]string)
	for k, v := range jsonMap {
		result[k] = convertValue(reflect.ValueOf(v))
	}
	return result, nil
}
